package com.example.demo.service.serviceImpl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.config.WxPayConfig;
import com.example.demo.mapper.UserMapper;
import com.example.demo.mapper.VipDtoMapper;
import com.example.demo.mapper.VipPayOrderMapper;
import com.example.demo.pojo.R;
import com.example.demo.pojo.User.User;
import com.example.demo.pojo.vip.VipDto;
import com.example.demo.pojo.vip.Weixin.*;
import com.example.demo.service.WxPayService;
import com.example.demo.utils.TokenUtil.decryptToken;
import com.example.demo.utils.TokenUtil.spiltUtils;
import com.example.demo.utils.UserUtil;
import com.example.demo.utils.WeixinPayUtil.AesUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.util.EntityUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.security.GeneralSecurityException;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.Map;

import static com.example.demo.config.WxPayInfoConfig.*;
import static com.example.demo.utils.ConstantUtils.*;
import static com.example.demo.utils.WeixinPayUtil.WxOrderUtil.generateOrderNumber;

@Service
@Slf4j
public class WxPayServiceImpl extends ServiceImpl<VipPayOrderMapper, VipPayOrder> implements WxPayService {

    @Resource
    private WxPayConfig wxPayConfig;

    @Resource
    private VipPayOrderMapper vipPayOrderMapper;

    @Resource
    private UserUtil userUtil;

    @Resource
    private UserMapper userMapper;

    @Resource
    private VipDtoMapper vipDtoMapper;

//    @Override
//    @Transactional
//    public R<T> CreateOrder(String token, Integer total, String description) {
//        //获取当前用户的用户名
//        String decrypt = decryptToken.decrypt(token);
//        String userName = spiltUtils.getUserName(decrypt);
//        Integer userId = userUtil.getUserId(userName);
//        //判断用户是否已经是vip用户
//        QueryWrapper<VipDto> vipDtoQueryWrapper = new QueryWrapper<>();
//        vipDtoQueryWrapper.eq("user_id", userId).eq("status", UNEXPIRED);
//        VipDto vipDto = vipDtoMapper.selectOne(vipDtoQueryWrapper);
//        if (vipDto != null) {
//            return R.failed("你已经是vip用户了，请过期后再充值！");
//        }
//        //请求URL
//        HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/native");
//        // 设置连接超时和读取超时
//        RequestConfig requestConfig = RequestConfig.custom()
//                .setConnectTimeout(5000)
//                .setSocketTimeout(5000)
//                .build();
//        httpPost.setConfig(requestConfig);
//        //请求参数
//        Amount amount = Amount.builder()
//                .total(total)
//                .currency("CNY")
//                .build();
//        //生成订单号（当前时间戳+uuid+随机的五个字母）
//        String out_trade_no = generateOrderNumber();
//        WxOnePayVo.WxOnePayVoBuilder wxOnePayVoBuilder = WxOnePayVo.builder()
//                .mchid(mchId)
//                .appid(appid)
//                .description(description)
//                .out_trade_no(out_trade_no)
//                .notify_url(pay_notify_url)
//                .amount(amount);
//        // 请求body参数
//        String reqdata = JSON.toJSONString(wxOnePayVoBuilder);
//        StringEntity entity = new StringEntity(reqdata, "utf-8");
//        entity.setContentType("application/json");
//        httpPost.setEntity(entity);
//        httpPost.setHeader("Accept", "application/json");
//
//        //完成签名并执行请求
//        try (CloseableHttpResponse response = wxPayConfig.httpClient.execute(httpPost)) {
//            int statusCode = response.getStatusLine().getStatusCode();
//            if (statusCode == 200) {
//                //生成系统订单
//                VipPayOrder vipPayOrder = new VipPayOrder();
//                vipPayOrder.setOrderNo(out_trade_no);//订单号
//                vipPayOrder.setCreateTime(new Date());//生成时间
//                vipPayOrder.setUserId(userId);//用户id
//                vipPayOrder.setProductName(description);//产品名称
//                vipPayOrder.setOrderAmount(BigDecimal.valueOf(total));//支付金额
//                vipPayOrder.setOrderStatus(PENDING_PAYMENT);//支付状态
//                vipPayOrder.setPaymentType("微信支付");
//                int insert = vipPayOrderMapper.insert(vipPayOrder);
//                if (insert > 0) {
//                    log.info("success,return body = " + EntityUtils.toString(response.getEntity()));
//                    String code_url = JSON.parseObject(EntityUtils.toString(response.getEntity()), Map.class).get("code_url").toString();
//                    return R.success(code_url);
//                }
//            } else if (statusCode == 204) {
//                log.info("success");
//            } else {
//                log.info("failed,resp code = " + statusCode + ",return body = " + EntityUtils.toString(response.getEntity()));
//                throw new IOException("request failed");
//            }
//        } catch (IOException e) {
//            throw new RuntimeException(e);
//        } finally {
//            try {
//                wxPayConfig.httpClient.close();
//            } catch (IOException e) {
//                throw new RuntimeException(e);
//            }
//        }
//        return R.failed("订单生成失败！");
//    }

    @Override
    @Transactional
    public ResponseEntity<?> PayNotify(NotifyDto dto) {
        //解密微信传递过来的参数
        String decrypt;
        try {
            decrypt = new AesUtil(apiV3Key.getBytes()).decryptToString(dto.getResourceDto().getAssociated_data().getBytes()
                    , dto.getResourceDto().getNonce().getBytes()
                    , dto.getResourceDto().getCiphertext());
        } catch (GeneralSecurityException | IOException e) {
            log.error("解密微信通知参数失败", e);
            return ResponseEntity
                    .status(HttpStatus.INTERNAL_SERVER_ERROR) // 也可以选择其他4XX或5XX状态码
                    .body(new WxPayR("FAIL", "解密失败")); // 创建一个类或其他类来封装这些信息
        }
        //获取支付状态
        String tradeStateDesc = JSON.parseObject(decrypt, Map.class).get("trade_state_desc").toString();
        //如果支付成功
        if ("支付成功".equals(tradeStateDesc)) {
            //获取订单号
            String out_trade_no = JSON.parseObject(decrypt, Map.class).get("out_trade_no").toString();
            log.info("---------------支付成功订单号:" + out_trade_no);
            //修改订单支付状态
            UpdateWrapper<VipPayOrder> vipPayOrderQueryWrapper = new UpdateWrapper<>();
            vipPayOrderQueryWrapper.eq("order_no", out_trade_no)
                    .set("order_status", PAYMENT_SUCCESSFUL)
                    .set("payment_time", new Date());
            int update = vipPayOrderMapper.update(null, vipPayOrderQueryWrapper);
            if (update > 0) {
                //查询订单
                QueryWrapper<VipPayOrder> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("order_no", out_trade_no);
                Integer userId = vipPayOrderMapper.selectOne(queryWrapper).getUserId();
                //判断用户以前是否有过vip
                QueryWrapper<VipDto> vipDtoQueryWrapper = new QueryWrapper<>();
                vipDtoQueryWrapper.eq("user_id", userId).eq("status", EXPIRED);
                VipDto one = vipDtoMapper.selectOne(vipDtoQueryWrapper);
                if (one != null) {
                    UpdateWrapper<VipDto> vipDtoUpdateWrapper = new UpdateWrapper<>();
                    vipDtoUpdateWrapper.eq("user_id", userId)
                            .set("status", UNEXPIRED);
                    int vipUpdate = vipDtoMapper.update(null, vipDtoUpdateWrapper);
                    //修改用户状态
                    UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
                    userUpdateWrapper.eq("id", userId).set("role", VIP_USER_ROLE);
                    int userUpdate = userMapper.update(null, userUpdateWrapper);
                    if (vipUpdate > 0 && userUpdate > 0){
                        return ResponseEntity.ok().body(new WxPayR("SUCCESS", "支付成功！")); // 使用状态码200
                    }
                }
                //添加用户vip逻辑
                VipDto vipDto = new VipDto();
                vipDto.setUserId(userId);
                vipDto.setStatus(UNEXPIRED);
                // 获取当前时间
                LocalDateTime now = LocalDateTime.now();
                vipDto.setStartTime(now);
                // 将当前时间延期一个月
                LocalDateTime oneMonthLater = now.plus(1, ChronoUnit.MONTHS);
                // 设置vipDto的结束时间为当前时间延期一个月
                vipDto.setEndTime(oneMonthLater);
                int insert = vipDtoMapper.insert(vipDto);
                //修改用户状态
                UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
                userUpdateWrapper.eq("id", userId).set("role", VIP_USER_ROLE);
                int userUpdate = userMapper.update(null, userUpdateWrapper);
                if (insert > 0 && userUpdate > 0) {
                    return ResponseEntity.ok().body(new WxPayR("SUCCESS", "支付成功！")); // 使用状态码200
                }
            }
        }
        //支付失败
        //获取订单号
        String out_trade_no = JSON.parseObject(decrypt, Map.class).get("out_trade_no").toString();
        log.info("------------支付失败订单号:" + out_trade_no);
        //修改订单支付状态
        UpdateWrapper<VipPayOrder> vipPayOrderQueryWrapper = new UpdateWrapper<>();
        vipPayOrderQueryWrapper.eq("order_no", out_trade_no)
                .set("order_status", PAYMENT_FAILED)
                .set("payment_time", new Date());
        return ResponseEntity
                .status(HttpStatus.INTERNAL_SERVER_ERROR) // 也可以选择其他4XX或5XX状态码
                .body(new WxPayR("FAIL", "支付失败")); // 创建一个类或其他类来封装这些信息
    }

//    @Override
//    @Transactional
//    public R<T> CloseOrder(String outTradeNo) {
//        String url = String.format(WxPayInfoConfig.closeUrl, outTradeNo);
//        //请求URL
//        HttpPost httpPost = new HttpPost(url);
//        String reqdata = "{\"mchid\": \"" + mchId + "\"}";
//
//        StringEntity entity = new StringEntity(reqdata, "utf-8");
//        entity.setContentType("application/json");
//        httpPost.setEntity(entity);
//        httpPost.setHeader("Accept", "application/json");
//
//        //完成签名并执行请求
//        CloseableHttpResponse response;
//        try {
//            response = wxPayConfig.httpClient.execute(httpPost);
//        } catch (IOException e) {
//            throw new RuntimeException(e);
//        }
//        try {
//            int statusCode = response.getStatusLine().getStatusCode();
//            if (statusCode == 200) {
//                try {
//                    log.info("success,return body = " + EntityUtils.toString(response.getEntity()));
//                    //取消系统订单
//                    log.info("-----------------取消订单订单号:" + outTradeNo);
//                    UpdateWrapper<VipPayOrder> updateWrapper = new UpdateWrapper<>();
//                    updateWrapper.eq("order_no", outTradeNo)
//                            .set("order_status", CANCELED);
//                    int update = vipPayOrderMapper.update(null, updateWrapper);
//                    if (update > 0) {
//                        return R.success("订单已取消！");
//                    }
//                } catch (IOException e) {
//                    throw new RuntimeException(e);
//                }
//            } else if (statusCode == 204) {
//                log.info("success");
//            } else {
//                try {
//                    log.info("failed,resp code = " + statusCode + ",return body = " + EntityUtils.toString(response.getEntity()));
//                    log.info("-----------------取消失败订单订单号:" + outTradeNo);
//                    return R.failed("订单取消失败！");
//                } catch (IOException e) {
//                    throw new RuntimeException(e);
//                }
//            }
//        } finally {
//            try {
//                response.close();
//            } catch (IOException e) {
//                throw new RuntimeException(e);
//            }
//        }
//        return R.failed("订单取消失败！");
//    }
//
//    @Override
//    public R<T> QueryOrder(String outTradeNo) {
//
//        //请求URL
//        URIBuilder uriBuilder;
//        String url = String.format(queryUrl, outTradeNo, WxPayInfoConfig.mchId);
//        try {
//            uriBuilder = new URIBuilder(url);
//        } catch (URISyntaxException e) {
//            throw new RuntimeException(e);
//        }
//        uriBuilder.setParameter("mchid", mchId);
//
//        //完成签名并执行请求
//        HttpGet httpGet;
//        try {
//            httpGet = new HttpGet(uriBuilder.build());
//        } catch (URISyntaxException e) {
//            throw new RuntimeException(e);
//        }
//        httpGet.addHeader("Accept", "application/json");
//
//        try (CloseableHttpResponse response = wxPayConfig.httpClient.execute(httpGet)) {
//            int statusCode = response.getStatusLine().getStatusCode();
//            if (statusCode == 200) {
//                log.info("success,return body = " + EntityUtils.toString(response.getEntity()));
//            } else if (statusCode == 204) {
//                log.info("success");
//            } else {
//                log.info("failed,resp code = " + statusCode + ",return body = " + EntityUtils.toString(response.getEntity()));
//                throw new IOException("request failed");
//            }
//        } catch (IOException e) {
//            throw new RuntimeException(e);
//        }
//        return R.failed();
//    }
}
